package part14语言包.class类;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Class类 特殊的类  
 * 反射： 获取/窃取/偷窥 其他类的内部细节（成员属性 成员方法）还可以访问调用。不能直接访问，需要帮手。
 * @author Administrator
 *
 */
public class 反射 {

	public static void main(String[] args) throws Exception {
		//创建Person类的类对象
		Class personClass0  = Person.class;
		Class personClass =Class.forName("part14语言包.class类.Person");
		
		// 通过Class类对象 获取Person类的内部细节
		System.out.println("--获取公共的构造方法---");
		// 1 获取构造方法Constructor<?>[] getConstructors() 返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造 类对象。  
		Constructor[] constructors = personClass.getConstructors();
		for (Constructor c : constructors) {
			System.out.println("构造方法名：" + c.getName() + ",修饰符： " + c.getModifiers() +",形参个数：" + c.getParameterCount());
		}
		System.out.println("--获取所有的构造的方法---");
		// 2 获取所有的构造方法 Constructor<?>[] getDeclaredConstructors()  返回一个反映 Constructor对象表示的类声明的所有 Constructor对象的数组 类 。 
		Constructor[] constructors2 = personClass.getDeclaredConstructors();
		for (Constructor c : constructors2) {
			System.out.println("构造方法名：" + c.getName() + ",修饰符： " + c.getModifiers() +",形参个数：" + c.getParameterCount());
		}
		System.out.println("--获取公共的方法---");
		// 3 获取方法 方法[] getMethods() 返回包含一个数组 方法对象反射由此表示的类或接口的所有公共方法 类对象，包括那些由类或接口和那些从超类和超接口继承的声明。  
		Method[] methods = personClass.getMethods();
		for (Method method : methods) {
			System.out.println("方法名" + method.getName() + ",形参个数：" +  method.getParameterCount());
		}
		System.out.println("--获取所有的方法---");
		// 获取所有的方法 getDeclaredMethods() 返回包含一个数组方法对象反射的类或接口的所有声明的方法，通过此表示类对象，包括公共，保护，默认（包）访问和私有方法，但不包括继承的方法。 
		Method[] methods2 = personClass.getDeclaredMethods();
		for (Method method : methods2) {
			System.out.println("方法名" + method.getName() + ",形参个数：" +  method.getParameterCount());
		}
		// 4 获取成员属性
		System.out.println("--所有的成员属性---");
		Field[] declaredFields = personClass.getDeclaredFields();
		for (Field field : declaredFields) {
			System.out.println("属性名：" + field.getName());
		}
		// 5如何访问(调用)方法
//		getMethod("方法名",参数的类对象);
		Method method = personClass.getMethod("setPname", String.class);
//		invoke(类的对象, 参数值);
		Person person = (Person) personClass.newInstance();
		method.invoke(person, "小白");
		
		Method method2 = personClass.getMethod("getPname", null);
		// 执行方法
		String result = (String) method2.invoke(person, null);
		System.out.println("getPname的返回值：" + result);
		
		Method method3 = personClass.getMethod("t",null);
		method3.invoke(person, null);
		
		Method method4 = personClass.getMethod("t3",int.class,double.class);
		method4.invoke(person,1000,25.555);
		
		Method method5 = personClass.getMethod("t4",Integer.class,Double.class);
		method5.invoke(person,1,15.56);
		
		// 6如何操作成员属性
		// 获取单个成员属性
		Field declaredField = personClass.getDeclaredField("pname");
		// 无法直接操作私有属性，必须开启操作权限，关闭java语言的访问检查。
		declaredField.setAccessible(true);
		// 设置值
		declaredField.set(person, "大黑");
		// 获取值
		System.out.println(declaredField.get(person));
	}
}
